package cn.jbolt.ai.core.chain.node.action;

import cn.hutool.core.util.StrUtil;
import cn.jbolt.ai.app.entity.AiAppMessage;
import cn.jbolt.ai.app.service.AiAppMessageService;
import cn.jbolt.ai.core.chain.ChainContext;
import cn.jbolt.ai.core.chain.config.AppConfigConstant;
import cn.jbolt.ai.core.chain.config.FuncChatNodeConfig;
import cn.jbolt.ai.core.chain.config.LlmConfig;
import cn.jbolt.ai.core.chain.node.provider.BaseNode;
import cn.jbolt.ai.core.chain.node.provider.EventNodeProvider;
import com.fasterxml.jackson.databind.JsonNode;
import com.jboltai.capability.model.JBoltAI;
import com.jboltai.event.Event;
import com.jboltai.event.ai.aichat.AIChatEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


/**
 * 知识库回答的节点
 */
@Component
public class FuncChatNodeProvider extends BaseNode implements EventNodeProvider<Event> {

    @Autowired
    private AiAppMessageService aiAppMessageService;
    private static final Logger logger = LoggerFactory.getLogger(FuncChatNodeProvider.class);


    private static final String TEMPLATE = "# Role: 结构化数据解析与展示专家\n" +
            "\n" +
            "## 任务背景\n" +
            "用户提出了以下问题：\n" +
            "\"\"\"\n" +
            "{{}}\n" +
            "\"\"\"\n" +
            "\n" +
            "我们已通过匹配的Function完成数据获取：\n" +
            "▸ 功能描述：{{}}\n" +
            "▸ 执行结果：{{}}\n" +
            "\n" +
            "## 处理要求\n" +
            "1. **信息解析**：\n" +
            "   - 提取与用户问题直接相关的核心数据\n" +
            "   - 过滤无关字段和冗余信息\n" +
            "   - 识别数据间的逻辑关系\n" +
            "\n" +
            "2. **展示优化**：\n" +
            "   - 根据数据类型选择最佳呈现方式：\n" +
            "     ✓ 单个数据 → 普通文本\n" +
            "     ✓ 简单列表 → 无序列表\n" +
            "     ✓ 结构化数据 → 表格\n" +
            "     ✓ 代码/配置 → 代码块\n" +
            "     ✓ 层级关系 → 嵌套列表\n" +
            "   - 如果非常有必要，则添加适当的中文解读说明\n" +
            "   - 保持专业性与可读性平衡\n" +
            "\n" +
            "## 输出规范\n" +
            "◆ 根据问题和数据使用合适的Markdown格式输出，但不允许外层嵌套```markdown\n" +
            "◆ 不允许输出无关的解释性和说明性文字\n"
            ;

    public Event provide(JsonNode nodeConfig, ChainContext context) {
        try {
            LlmConfig llmConfig = LlmConfig.from(nodeConfig.get(AppConfigConstant.CONFIG_TYPE_LLM));
            FuncChatNodeConfig funcChatConfig = FuncChatNodeConfig.from(nodeConfig.get(AppConfigConstant.CONFIG_TYPE_FUNCCHAT));
            if (funcChatConfig == null) {
                logger.error("应用 [{}:{}] function call节点未配置", context.getAiApp().getSn(), context.getAiApp().getName());
                throw new RuntimeException("节点未配置");
            }
            if (StrUtil.isBlank(llmConfig.getInputField())) {
                logger.error("未配置问题字段");
                throw new RuntimeException("未配置问题字段");
            }
            if (StrUtil.isBlank(funcChatConfig.getFuncCallResultField())) {
                logger.error("未配置函数调用结果字段");
                throw new RuntimeException("未配置函数调用结果字段");
            }
            if (StrUtil.isBlank(funcChatConfig.getMatchFunctionField())) {
                logger.error("未配置函数匹配结果字段");
                throw new RuntimeException("未配置函数匹配结果字段");
            }

            AIChatEvent event = JBoltAI.chat();


            //根据配置初始化event
            super.configLlm(llmConfig, context, event);
            //使用模板重新生成提示词
            event.prompt(TEMPLATE, event.getPrompt(),
                    valueToString(context.getAttr(funcChatConfig.getMatchFunctionField())),
                    valueToString(context.getAttr(funcChatConfig.getFuncCallResultField()))
            );
            event.onSuccess((e, res) -> {
                if (llmConfig.isOutputToResponse()) {
                    //如果配置项要求 内容返回到响应里，那就输出，默认是true的
                    //构建相应信息
                    context.sendResponseMsg(res.getContent(), llmConfig.getFormat());
                }
            });
            event.onFail((e, error) -> {
                logger.error("ChatWithFunction节点执行发生异常,异常原因:{}", error.getFullMsg());
            });

            event.onComplete((e) -> {

                switch (e.getState()) {
                    case SUCCESS:
                        //事件执行成功
                        if (StrUtil.isNotBlank(funcChatConfig.getOutputField())) {
                            //配置项要求，把结果输出到上下文
                            context.setAttr(funcChatConfig.getOutputField(), e.getResult());
                        }
                    case CANCEL:
                        if (llmConfig.isPersistDb()) {//成功或者取消 需要持久化数据
                            //把答案给存储
                            context.getResponseMsg().appendContent(e.getResult().getContent());
                        }
                        break;
                    case FAIL:

                }

            });
            return event;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("FuncChatNodeProvider process 异常,异常原因", e);
            context.sendErrorMsg("网络异常,请稍后重试....");
        }
        return null;
    }


}
